#include "point_setting_widget.h"
#include "ui_point_setting_widget.h"
#include <QDebug>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QVariant>
#include <QSqlError>
#include "database_manager.h"
#include <QMessageBox>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>
#include "dealer_handler.h"
PointSettingWidget::PointSettingWidget(QWidget *parent)
    : QWidget(parent),
      ui_(new Ui::PointSettingWidget),
      dealer_handler_(DealerHandler::getInstance())
{
    ui_->setupUi(this);

    connect(ui_->saveProtocalBtn, &QPushButton::clicked,
            this, &PointSettingWidget::onSaveProtocalBtnClicked);

    // 连接新增按钮信号
    connect(ui_->addYXBtn, &QPushButton::clicked, this, &PointSettingWidget::onAddButtonClicked);
    connect(ui_->addYKBtn, &QPushButton::clicked, this, &PointSettingWidget::onAddButtonClicked);
    connect(ui_->addYCBtn, &QPushButton::clicked, this, &PointSettingWidget::onAddButtonClicked);
    connect(ui_->addYTBtn, &QPushButton::clicked, this, &PointSettingWidget::onAddButtonClicked);

    connect(ui_->settingBtn, &QPushButton::clicked, this, &PointSettingWidget::onSettingButtonClicked);
    connect(dealer_handler_, &DealerHandler::messageReceived, this, &PointSettingWidget::onNetworkResponse);

    connect(ui_->toolBox, &QToolBox::currentChanged, this, &PointSettingWidget::onToolBoxChanged);

    // 调整遥信表样式，设置各列的宽度
    ui_->yxTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
    ui_->yxTable->setColumnWidth(0, 50);
    ui_->yxTable->setColumnWidth(1, 100);
    ui_->yxTable->setColumnWidth(3, 100);

    // 调整遥控表样式，设置各列的宽度
    ui_->ykTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
    ui_->ykTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
    ui_->ykTable->setColumnWidth(0, 50);
    ui_->ykTable->setColumnWidth(1, 100);
    ui_->ykTable->setColumnWidth(4, 200);

    // 调整遥测表样式，设置各列的宽度
    ui_->ycTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
    ui_->ycTable->setColumnWidth(0, 50);
    ui_->ycTable->setColumnWidth(1, 100);
    ui_->ycTable->setColumnWidth(3, 200);

    // 调整遥调表样式，设置各列的宽度
    ui_->ytTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
    ui_->ytTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
    ui_->ytTable->setColumnWidth(0, 50);
    ui_->ytTable->setColumnWidth(1, 100);
    ui_->ytTable->setColumnWidth(4, 200);
}

PointSettingWidget::~PointSettingWidget()
{
    delete ui_;
}

void PointSettingWidget::setSearchTreeWidget(SearchTreeWidget *search_tree_widget)
{
    search_tree_widget_ = search_tree_widget;
    connect(search_tree_widget_, &SearchTreeWidget::itemClicked,
            this, &PointSettingWidget::onSearchTreeWidgetItemClicked);
}

void PointSettingWidget::onSearchTreeWidgetItemClicked(StateInfo state_info)
{
    state_info_ = state_info;
    if (state_info.isRtu())
    {
        ui_->stationNameInput->setText(state_info.stateName());
    }

    bool is_ok = false;
    point_setting_ = DatabaseManager::queryPointAddressConfig(state_info_.id(), is_ok);
    if (is_ok)
    {
        ui_->yxStartAddrInput->setValue(point_setting_.yx_addr_start);
        ui_->ycStartAddrInput->setValue(point_setting_.yc_addr_start);
        ui_->powerStartAddrInput->setValue(point_setting_.dd_addr_start);
        ui_->ykStartAddrInput->setValue(point_setting_.yk_addr_start);
        ui_->ytStartAddrInput->setValue(point_setting_.yt_addr_start);
        ui_->soeStartAddrInput->setValue(point_setting_.soe_addr_start);
        qDebug() << "遥信配置.规约配置加载成功";
    }

    renderYxTable(state_info_.id());
    renderYkTable(state_info_.id());
    renderYcTable(state_info_.id());
    renderYtTable(state_info_.id());
}

void PointSettingWidget::showEvent(QShowEvent *event)
{
    QWidget::showEvent(event);
}

void PointSettingWidget::hideEvent(QHideEvent *event)
{
    QWidget::hideEvent(event);
}

void PointSettingWidget::onSaveProtocalBtnClicked()
{
    bool ok;
    point_setting_.yx_addr_start = ui_->yxStartAddrInput->text().toInt(&ok, 16);
    point_setting_.yc_addr_start = ui_->ycStartAddrInput->text().toInt(&ok, 16);
    point_setting_.dd_addr_start = ui_->powerStartAddrInput->text().toInt(&ok, 16);
    point_setting_.yk_addr_start = ui_->ykStartAddrInput->text().toInt(&ok, 16);
    point_setting_.yt_addr_start = ui_->ytStartAddrInput->text().toInt(&ok, 16);
    point_setting_.soe_addr_start = ui_->soeStartAddrInput->text().toInt(&ok, 16);

    if (DatabaseManager::savePointAddressConfig(state_info_.id(),
                                                point_setting_.yx_addr_start,
                                                point_setting_.yc_addr_start,
                                                point_setting_.dd_addr_start,
                                                point_setting_.yk_addr_start,
                                                point_setting_.yt_addr_start,
                                                point_setting_.soe_addr_start))
    {
        QMessageBox::information(this, "提示", "点表地址配置保存成功");
    }
    else
    {
        QMessageBox::warning(this, "错误", "点表地址配置保存失败");
    }
}

void PointSettingWidget::onAddButtonClicked()
{
    QPushButton *button = qobject_cast<QPushButton *>(sender());
    if (!button)
    {
        return;
    }

    PointInfo::Type type;
    QTableWidget *table = nullptr;
    uint64_t addr_offset = 0;

    if (button == ui_->addYXBtn)
    {
        type = PointInfo::Type::YX;
        table = ui_->yxTable;
        addr_offset = point_setting_.yx_addr_start;
    }
    else if (button == ui_->addYKBtn)
    {
        type = PointInfo::Type::YK;
        table = ui_->ykTable;
        addr_offset = point_setting_.yk_addr_start;
    }
    else if (button == ui_->addYCBtn)
    {
        type = PointInfo::Type::YC;
        table = ui_->ycTable;
        addr_offset = point_setting_.yc_addr_start;
    }
    else if (button == ui_->addYTBtn)
    {
        type = PointInfo::Type::YT;
        table = ui_->ytTable;
        addr_offset = point_setting_.yt_addr_start;
    }
    else
    {
        return;
    }

    PointAddDialog dialog(type, state_info_.id(), this);
    if (dialog.exec() == QDialog::Accepted)
    {
        int point_number = dialog.getPointNumber();
        QString physical_info = dialog.getPhysicalInfo();
        int related_point = dialog.getRelatedPoint();

        // 计算实际地址
        uint64_t actual_addr = point_number + addr_offset;

        // 插入数据库
        int ret = DatabaseManager::insertPoint(state_info_.id(), static_cast<int>(type), actual_addr, physical_info, 0);
        if (ret != 0)
        {
            QMessageBox::warning(this, "错误", "插入数据失败：" + QString::number(ret));
            return;
        }

        // 如果是遥控或遥调类型，则插入关联关系
        if (type == PointInfo::Type::YK || type == PointInfo::Type::YT)
        {
            ret = DatabaseManager::insertPointRelation(state_info_.id(), actual_addr, related_point);
            if (ret != 0)
            {
                QMessageBox::warning(this, "错误", "插入关联关系失败：" + QString::number(ret));
                return;
            }
        }
        // 重新渲染表格
        renderYxTable(state_info_.id());
        renderYkTable(state_info_.id());
        renderYcTable(state_info_.id());
        renderYtTable(state_info_.id());
    }
}

void PointSettingWidget::onDeleteButtonClicked()
{
    QPushButton *button = qobject_cast<QPushButton *>(sender());
    if (!button)
    {
        return;
    }

    int row = button->property("row").toInt();
    int64_t point_addr = button->property("point_addr").toLongLong();

    // 确认删除
    QMessageBox::StandardButton reply = QMessageBox::question(this, "确认删除",
                                                              "确定要删除这个点吗？",
                                                              QMessageBox::Yes | QMessageBox::No);

    if (reply == QMessageBox::Yes)
    {
        // 调用删除函数
        if (DatabaseManager::deletePoints(state_info_.id(), point_addr))
        {
            // 获取当前表格
            QTableWidget *table = nullptr;
            QList<QTableWidget *> tables = {ui_->yxTable, ui_->ykTable, ui_->ycTable, ui_->ytTable};
            for (QTableWidget *t : tables)
            {
                for (int i = 0; i < t->rowCount(); ++i)
                {
                    QWidget *cellWidget = t->cellWidget(i, t->columnCount() - 1);
                    if (cellWidget == button)
                    {
                        table = t;
                        break;
                    }
                }
                if (table)
                {
                    break;
                }
            }

            if (table)
            {
                // 清空表格
                table->setRowCount(0);

                // 根据表格类型重新加载数据
                PointInfo::Type type;
                if (table == ui_->yxTable)
                {
                    type = PointInfo::Type::YX;
                }
                else if (table == ui_->ykTable)
                {
                    type = PointInfo::Type::YK;
                }
                else if (table == ui_->ycTable)
                {
                    type = PointInfo::Type::YC;
                }
                else if (table == ui_->ytTable)
                {
                    type = PointInfo::Type::YT;
                }
                else
                {
                    return;
                }

                // 如果是遥控或遥调类型，则正向删除关联关系, 否则反向删除关联关系
                if (type == PointInfo::Type::YK || type == PointInfo::Type::YT)
                {
                    DatabaseManager::deletePointRelation(state_info_.id(), point_addr);
                }
                else
                {
                    DatabaseManager::reverseDeletePointRelation(state_info_.id(), point_addr);
                }

                renderYxTable(state_info_.id());
                renderYkTable(state_info_.id());
                renderYcTable(state_info_.id());
                renderYtTable(state_info_.id());
            }
        }
    }
}

void PointSettingWidget::onSettingButtonClicked()
{
    {
        QVector<PointInfo> points = DatabaseManager::queryAllPoints();
        // 将points中的点信息转换为json格式
        QJsonArray jsonArray;
        for (const auto &point : points)
        {
            QJsonObject jsonObject;
            jsonObject["pointId"] = point.point_id;
            jsonObject["pointDesc"] = point.point_desc;
            jsonObject["pointType"] = point.point_type;
            jsonObject["direction"] = point.direction;
            jsonObject["substationId"] = point.station_id;
            jsonArray.append(jsonObject);
        }
        // 将jsonArray转换为json格式
        QJsonDocument jsonDocument;
        jsonDocument.setArray(jsonArray);
        QString jsonString = jsonDocument.toJson(QJsonDocument::Compact);
        dealer_handler_->sendRequest("set-point-filter", jsonString);
    }
    {
        QVector<PointInfo> point_relations = DatabaseManager::queryAllPointRelation();
        QJsonArray jsonArray;
        for (const auto &point : point_relations)
        {
            QJsonObject jsonObject;
            jsonObject["stationId"] = point.station_id;
            jsonObject["pointCtrl"] = point.point_id;
            jsonObject["pointGrab"] = point.relation_point_address;
            jsonArray.append(jsonObject);
        }
        // 将jsonArray转换为json格式
        QJsonDocument jsonDocument;
        jsonDocument.setArray(jsonArray);
        QString jsonString = jsonDocument.toJson(QJsonDocument::Compact);
        dealer_handler_->sendRequest("set-point-relation", jsonString);
    }
}

void PointSettingWidget::onNetworkResponse(const QString &method, const QString &body)
{
    if (method == "set-point-filter")
    {
        if (body == "success")
        {
            QMessageBox::information(this, "提示", "点表配置保存成功");
        }
        else
        {
            QMessageBox::warning(this, "错误", "点表配置保存失败");
        }
    }

    if (method == "set-point-relation")
    {
        if (body == "success")
        {
            QMessageBox::information(this, "提示", "点表关联关系保存成功");
        }
        else
        {
            QMessageBox::warning(this, "错误", "点表关联关系保存失败");
        }
    }
}

void PointSettingWidget::renderYxTable(int64_t station_id)
{
    // 查询点表遥信类型，并渲染到表格中
    QVector<PointInfo> yx_points = DatabaseManager::queryPoints(state_info_.id(), static_cast<int>(PointInfo::Type::YX));
    // 渲染到yxTable
    ui_->yxTable->setRowCount(yx_points.size());
    for (int i = 0; i < yx_points.size(); ++i)
    {
        ui_->yxTable->setItem(i, 0, new QTableWidgetItem(QString::number(i + 1)));
        ui_->yxTable->setItem(i, 1, new QTableWidgetItem(QString::number(yx_points[i].point_id - point_setting_.yx_addr_start)));
        ui_->yxTable->setItem(i, 2, new QTableWidgetItem(yx_points[i].point_desc));

        // 添加删除按钮
        QPushButton *deleteBtn = new QPushButton("删除");
        deleteBtn->setObjectName("deleteButton");
        deleteBtn->setProperty("row", i);
        deleteBtn->setProperty("point_addr", yx_points[i].point_id);
        connect(deleteBtn, &QPushButton::clicked, this, &PointSettingWidget::onDeleteButtonClicked);
        ui_->yxTable->setCellWidget(i, ui_->yxTable->columnCount() - 1, deleteBtn);
    }
    ui_->yxTable->resizeColumnToContents(2);
    qDebug() << "四遥配置.遥信点表渲染完成";
}

void PointSettingWidget::renderYkTable(int64_t station_id)
{
    // 查询遥控点表
    QVector<PointInfo> yk_points = DatabaseManager::queryPoints(state_info_.id(), static_cast<int>(PointInfo::Type::YK));

    // 渲染到ykTable
    ui_->ykTable->setRowCount(yk_points.size());
    for (int i = 0; i < yk_points.size(); ++i)
    {
        ui_->ykTable->setItem(i, 0, new QTableWidgetItem(QString::number(i + 1)));
        ui_->ykTable->setItem(i, 1, new QTableWidgetItem(QString::number(yk_points[i].point_id - point_setting_.yk_addr_start)));
        ui_->ykTable->setItem(i, 2, new QTableWidgetItem(yk_points[i].point_desc));

        // 查询关联点
        int64_t related_point = DatabaseManager::queryPointGrab(state_info_.id(), yk_points[i].point_id);
        qDebug() << "四遥配置.遥控点表.查询关联点:" << related_point;
        QVector<PointInfo> yx_points = DatabaseManager::queryPoints(state_info_.id(), static_cast<int>(PointInfo::Type::YX));
        // 遍历遥信点找到和related_point相同的point
        for (const auto &yx_point : yx_points)
        {
            if (yx_point.point_id == related_point)
            {
                ui_->ykTable->setItem(i, 3, new QTableWidgetItem(QString("%1(%2)").arg(QString::number(related_point - point_setting_.yx_addr_start)).arg(yx_point.point_desc)));
            }
        }

        // 添加删除按钮
        QPushButton *deleteBtn = new QPushButton("删除");
        deleteBtn->setObjectName("deleteButton");
        deleteBtn->setProperty("row", i);
        deleteBtn->setProperty("point_addr", yk_points[i].point_id);
        connect(deleteBtn, &QPushButton::clicked, this, &PointSettingWidget::onDeleteButtonClicked);
        ui_->ykTable->setCellWidget(i, ui_->ykTable->columnCount() - 1, deleteBtn);
    }
    ui_->ykTable->resizeColumnToContents(2);
    qDebug() << "四遥配置.遥控点表渲染完成";
}

void PointSettingWidget::renderYcTable(int64_t station_id)
{
    // 查询遥测点表
    QVector<PointInfo> yc_points = DatabaseManager::queryPoints(state_info_.id(), static_cast<int>(PointInfo::Type::YC));
    // 渲染到ycTable
    ui_->ycTable->setRowCount(yc_points.size());
    for (int i = 0; i < yc_points.size(); ++i)
    {
        ui_->ycTable->setItem(i, 0, new QTableWidgetItem(QString::number(i + 1)));
        ui_->ycTable->setItem(i, 1, new QTableWidgetItem(QString::number(yc_points[i].point_id - point_setting_.yc_addr_start)));
        ui_->ycTable->setItem(i, 2, new QTableWidgetItem(yc_points[i].point_desc));

        // 添加删除按钮
        QPushButton *deleteBtn = new QPushButton("删除");
        deleteBtn->setObjectName("deleteButton");
        deleteBtn->setProperty("row", i);
        deleteBtn->setProperty("point_addr", yc_points[i].point_id);
        connect(deleteBtn, &QPushButton::clicked, this, &PointSettingWidget::onDeleteButtonClicked);
        ui_->ycTable->setCellWidget(i, ui_->ycTable->columnCount() - 1, deleteBtn);
    }
    ui_->ycTable->resizeColumnToContents(2);
    qDebug() << "四遥配置.遥测点表渲染完成";
}

void PointSettingWidget::renderYtTable(int64_t station_id)
{
    // 查询遥调点表
    QVector<PointInfo> yt_points = DatabaseManager::queryPoints(state_info_.id(), static_cast<int>(PointInfo::Type::YT));
    // 渲染到ytTable
    ui_->ytTable->setRowCount(yt_points.size());
    for (int i = 0; i < yt_points.size(); ++i)
    {
        ui_->ytTable->setItem(i, 0, new QTableWidgetItem(QString::number(i + 1)));
        ui_->ytTable->setItem(i, 1, new QTableWidgetItem(QString::number(yt_points[i].point_id - point_setting_.yt_addr_start)));
        ui_->ytTable->setItem(i, 2, new QTableWidgetItem(yt_points[i].point_desc));

        // 查询关联点
        int64_t related_point = DatabaseManager::queryPointGrab(state_info_.id(), yt_points[i].point_id);
        qDebug() << "四遥配置.遥调点表.查询关联点:" << related_point;
        QVector<PointInfo> yc_points = DatabaseManager::queryPoints(state_info_.id(), static_cast<int>(PointInfo::Type::YC));
        for (const auto &yc_point : yc_points)
        {
            if (yc_point.point_id == related_point)
            {
                ui_->ytTable->setItem(i, 3, new QTableWidgetItem(QString("%1(%2)").arg(QString::number(related_point - point_setting_.yc_addr_start)).arg(yc_point.point_desc)));
            }
        }

        // 添加删除按钮
        QPushButton *deleteBtn = new QPushButton("删除");
        deleteBtn->setObjectName("deleteButton");
        deleteBtn->setProperty("row", i);
        deleteBtn->setProperty("point_addr", yt_points[i].point_id);
        connect(deleteBtn, &QPushButton::clicked, this, &PointSettingWidget::onDeleteButtonClicked);
        ui_->ytTable->setCellWidget(i, ui_->ytTable->columnCount() - 1, deleteBtn);
    }
    ui_->ytTable->resizeColumnToContents(2);
    qDebug() << "四遥配置.遥调点表渲染完成";
}

void PointSettingWidget::onToolBoxChanged(int index)
{
    if (index == 1)
    {
        renderYxTable(state_info_.id());
    }
    else if (index == 2)
    {
        renderYkTable(state_info_.id());
    }
    else if (index == 3)
    {
        renderYcTable(state_info_.id());
    }
    else if (index == 4)
    {
        renderYtTable(state_info_.id());
    }
}